﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using WayneGameSolution.Packs;
namespace Console.Test
{
    class Program
    {

        static void Main(string[] args)
        {
            //TestTTTT();

            RecursionVisitor<string> dir = new RecursionVisitor<string>(
                new string[] { @"I:\WorkSpace\个人研究\ConsoleApplication3" },
                s => Directory.GetDirectories(s),
                (rv, p) => System.Console.WriteLine("Visiting {0}", p),
                (rv, p) => System.Console.WriteLine("Visited {0}", p));

            dir.Start();


            System.AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);



            System.AppDomain.CurrentDomain.GetAssemblies().ForEach((o, i) => showAsm(o));
            s_ds_TestBinSlim();
            s_ds_TestSoap();
            s_ds_TestBin();
            s_ds_TestNet();

            System.Console.ReadKey();

            //          var p = DataPack.Create(0);
        }

        static void s_ds_TestNet()
        {
            var c = WayneGameSolution.Communicate.Codec.NetDataContract;
            Pack_ChatMessage p = new Pack_ChatMessage() { P_Message = "haha" };
            p.P_SubChild1.NodeValue = "xxx";
            p.P_SubChild1.P_ChatToUserID1 = "123";
            p.P_Chats = new List<int>() { 1, 2, 3, 54, 5 };
            var bs = c.ToBytes(WayneGameSolution.Communicate.Crypt.EmptyCrypt, p);
            System.Console.WriteLine(bs.Length);
            var r = c.ToDataPack(WayneGameSolution.Communicate.Crypt.EmptyCrypt, bs, 1, 1);
           // System.Console.WriteLine(((Pack_ChatMessage.SubChild)r.DataRoot["SubChild1"]).P_ChatToUserID1);
            System.Console.ReadKey();
        }
        static void s_ds_TestBinSlim()
        {
            var c = WayneGameSolution.Communicate.Codec.JsonDataContract  ;
            Pack_ChatMessage p = new Pack_ChatMessage() { P_Message = "haha" };
            p.P_SubChild1.NodeValue = "xxx";
            p.P_SubChild1.P_ChatToUserID1 = "123";
            p.P_Chats = new List<int>() { 1, 2, 3, 54, 5 };
            var bs = c.ToBytes(WayneGameSolution.Communicate.Crypt.EmptyCrypt, p);
            System.Console.WriteLine(bs.Length);
            var r = c.ToDataPack(WayneGameSolution.Communicate.Crypt.EmptyCrypt, bs, p.Flag  , 1);
            // System.Console.WriteLine(((Pack_ChatMessage.SubChild)r.DataRoot["SubChild1"]).P_ChatToUserID1);
            System.Console.ReadKey();
        }
        static void showAsm(System.Reflection.Assembly asm)
        {
            System.Console.WriteLine("load : {0}", asm.FullName);
            var types = asm.GetTypes().ToList();
            types.Where(t => t.IsSubclassOf(typeof(WayneGameSolution.Packs.DataPack))).ToList().ForEach(x => System.Console.WriteLine("{0}--{1}", x.Namespace, x.Name));


        }

        static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
        {
            System.Console.WriteLine("Breaking load !!!");
            showAsm(args.LoadedAssembly);

        }






        static void s_ds_TestSoap()
        {
            var c = WayneGameSolution.Communicate.Codec.SoapFormatter ;
            Pack_ChatMessage p = new Pack_ChatMessage() { P_Message = "haha" };

            p.P_SubChild1.P_ChatToUserID1 = "123";
            var r = c.ToDataPack(WayneGameSolution.Communicate.Crypt.EmptyCrypt, c.ToBytes(WayneGameSolution.Communicate.Crypt.EmptyCrypt, p), 1, 1);
            var bs = c.ToBytes(WayneGameSolution.Communicate.Crypt.EmptyCrypt, p);
            System.Console.WriteLine(bs.Length);
            System.Console.ReadKey();

        }
        static void s_ds_TestBin()
        {
            var c = WayneGameSolution.Communicate.Codec.BinaryFormatter ;
            Pack_ChatMessage p = new Pack_ChatMessage() { P_Message = "haha" };

            p.P_SubChild1.P_ChatToUserID1 = "123";
            var r = c.ToDataPack(WayneGameSolution.Communicate.Crypt.EmptyCrypt, c.ToBytes(WayneGameSolution.Communicate.Crypt.EmptyCrypt, p), 1, 1);
            var bs = c.ToBytes(WayneGameSolution.Communicate.Crypt.EmptyCrypt, p);
            System.Console.WriteLine(bs.Length);
            System.Console.ReadKey();

        }



        static void TestTTTT()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Xml.XmlReader xr = System.Xml.XmlReader.Create(@"D:\wayne private\wgs-game-lobby\WGS\Classes\Packs\Packs.xml");
            List<String> PackNameList = new List<String>();
            Stack<string> currentClassName = new Stack<string>();
            Stack<string> currentPackFlag = new Stack<string>();
            Stack<string> currentType = new Stack<string>();
            StringBuilder attrib_sb = new StringBuilder();
            StringBuilder property_sb = new StringBuilder();
            StringBuilder class_sb = new StringBuilder();
            while (xr.Read())
            {
                string depthString = string.Empty.PadLeft(xr.Depth, '\t');

                if (xr.LocalName == "Properties")
                {
                    if (xr.IsStartElement())
                    {
                        StringBuilder current_sb;
                        System.Xml.XmlReader treader = xr.ReadSubtree();
                        Dictionary<String, string> mappingDic = new Dictionary<string, string>();
                        if (currentClassName.Peek().StartsWith("Pack_"))
                        { current_sb = property_sb; }
                        else
                        { current_sb = class_sb; };
                        while (treader.Read())
                        {
                            if (treader.LocalName == "Property")
                                if (treader.IsStartElement())
                                {
                                    if (treader.GetAttribute("Comment") != null)
                                    {
                                        current_sb.Append(depthString);
                                        current_sb.AppendLine("///<summary>");
                                        current_sb.Append(depthString);
                                        current_sb.AppendFormat("///{0}", treader.GetAttribute("Comment")).AppendLine();
                                        current_sb.Append(depthString);
                                        current_sb.AppendLine("///</summary>");
                                    }
                                    current_sb.Append(depthString);
                                    current_sb.AppendFormat("[DataMember ]public  {0}  P_{1}  ", treader.GetAttribute("ValueType"), treader.GetAttribute("Name")).Append("");
                                    current_sb.AppendLine(";");
                                    current_sb.AppendLine();
                                    mappingDic.Add(treader.GetAttribute("Name"), treader.GetAttribute("ValueType"));
                                }
                        }
                        current_sb.AppendLine();
                        current_sb.Append(depthString);
                        current_sb.AppendLine("///<summary>");
                        current_sb.Append(depthString);
                        current_sb.AppendFormat("///{0}", "节点属性 前面不需要加 P_").AppendLine();
                        current_sb.Append(depthString);
                        current_sb.AppendLine("///</summary>");
                        current_sb.Append(depthString);
                        current_sb.AppendLine("public object this[string AttributeName] ");
                        current_sb.Append(depthString);
                        current_sb.AppendLine("{ ");
                        current_sb.Append(depthString);
                        current_sb.AppendLine("get{ ");
                        foreach (KeyValuePair<string, string> kp in mappingDic)
                        {
                            current_sb.Append(depthString).Append('\t');
                            current_sb.AppendFormat("if (AttributeName==\"{0}\") return P_{0} ; ", kp.Key).AppendLine();
                        }
                        current_sb.Append(depthString);
                        current_sb.Append("\t");
                        current_sb.AppendLine("return null;");
                        current_sb.Append(depthString).Append('\t');
                        current_sb.AppendLine("}");
                        current_sb.Append(depthString);
                        current_sb.AppendLine("}");
                        current_sb.AppendLine();
                        current_sb.Append(depthString);


                        current_sb.AppendLine();
                        current_sb.Append(depthString);
                        current_sb.Append("static readonly String[] _PropertyNames=new String[] { ");
                        string tmp = string.Join(",", System.Linq.Enumerable.ToArray(mappingDic.Keys)).Replace(",", "\",\"");
                        if (tmp.Length != 0)
                        {
                            current_sb.Append('\"').Append(tmp).Append("\"");
                        }
                        current_sb.AppendLine("};");
                        current_sb.AppendLine();
                        current_sb.Append(depthString);
                        current_sb.AppendLine("///<summary>");
                        current_sb.Append(depthString);
                        current_sb.AppendFormat("///{0}", "属性名列表").AppendLine();
                        current_sb.Append(depthString);
                        current_sb.AppendLine("///</summary>");
                        current_sb.Append(depthString);
                        current_sb.AppendLine("public string[] PropertyNames {get {return _PropertyNames; }} ");


                    }


                }
                else if (xr.LocalName == "Child")
                {
                    if (xr.IsStartElement())
                    {
                        class_sb.AppendLine();
                        if (xr.GetAttribute("Comment") != null)
                        {
                            class_sb.AppendLine();
                            class_sb.Append(depthString);
                            class_sb.AppendLine("///<summary>");
                            class_sb.Append(depthString);
                            class_sb.AppendFormat("///{0}", xr.GetAttribute("Comment")).AppendLine();
                            class_sb.Append(depthString);
                            class_sb.AppendLine("///</summary>");
                        }
                        attrib_sb.AppendFormat("[KnownType (typeof ({0}))]", string.Join(".", System.Linq.Enumerable.ToArray(System.Linq.Enumerable.Reverse(currentClassName))));

                        currentClassName.Push(xr.GetAttribute("Name"));
                        class_sb.Append(depthString);
                        class_sb.Append("[DataContract ][Serializable]").AppendLine().Append(depthString).AppendFormat("public partial   struct  {0} :IPackNode ", xr.GetAttribute("Name")).AppendLine();
                        class_sb.Append(depthString);
                        class_sb.AppendLine("{");
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.AppendFormat("public  {0}  NodeValue  ", xr.GetAttribute("ValueType"));
                        class_sb.AppendLine(";");
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.Append("public  String NodeName  ");
                        class_sb.Append("{get {return \"").Append(xr.GetAttribute("Name")).AppendLine("\";}}");
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.Append("object IPackNode.NodeValue { get { return (Object)NodeValue; } set { NodeValue = (").Append(xr.GetAttribute("ValueType")).Append(")value; } }  ").AppendLine();
                    }
                    else
                    {
                        class_sb.Append(depthString);
                        class_sb.AppendLine("}").AppendLine();
                        currentClassName.Pop();
                    }

                }
                else if (xr.LocalName == "Pack")
                {

                    if (xr.IsStartElement())
                    {
                        property_sb = new StringBuilder();
                        attrib_sb = new StringBuilder();
                        class_sb = new StringBuilder();
                        PackNameList.Add(xr.GetAttribute("Name"));
                        if (xr.GetAttribute("Comment") != null)
                        {
                            class_sb.AppendLine().AppendLine();
                            class_sb.Append(depthString);
                            class_sb.AppendLine("/// <summary>");
                            class_sb.Append(depthString);
                            class_sb.AppendFormat("///{0}", xr.GetAttribute("Comment")).Append(":").Append(xr.GetAttribute("PackFlag")).AppendLine();
                            class_sb.Append(depthString);
                            class_sb.AppendLine("/// </summary>");
                        }
                        currentClassName.Push("Pack_" + xr.GetAttribute("Name"));
                        currentPackFlag.Push(xr.GetAttribute("PackFlag"));
                        currentType.Push(xr.GetAttribute("ValueType"));
                        class_sb.Append(depthString);
                        class_sb.AppendFormat("[DataContract ][Serializable][PackFlag (\"{0}\",{1})]", xr.GetAttribute("Name"), xr.GetAttribute("PackFlag")).AppendLine().Append(depthString).AppendFormat("public partial   class Pack_{0}:  Packs.DataPack,IPackNode  ", xr.GetAttribute("Name")).AppendLine();
                        class_sb.Append(depthString);
                        class_sb.AppendLine("{");
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.AppendFormat("[Microsoft.Practices.Unity.InjectionConstructor() ]public  Pack_{0}  ():base({1})  ", xr.GetAttribute("Name"), xr.GetAttribute("PackFlag")).AppendLine("{}");

                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.AppendFormat("public  {0}  NodeValue  ", xr.GetAttribute("ValueType"));
                        class_sb.AppendLine(";");
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.Append("public  String NodeName  ");
                        class_sb.Append("{get {return \"").Append(xr.GetAttribute("Name")).AppendLine("\";}}");

                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.Append("object IPackNode.NodeValue { get { return (Object)NodeValue; } set { NodeValue = (").Append(xr.GetAttribute("ValueType")).Append(")value; } }  ").AppendLine();
                        class_sb.Append(depthString);
                        class_sb.Append('\t');
                        class_sb.AppendLine("public override IPackNode DataRoot { get{return (IPackNode)this;}  }");

                    }
                    else
                    {
                        //sb.Append(depthString).AppendLine(attrib_sb.ToString());
                        sb.AppendLine(class_sb.ToString());
                        sb.AppendLine(property_sb.ToString());
                        sb.Append(depthString);
                        sb.AppendLine("}").AppendLine();
                        currentClassName.Pop();
                        currentPackFlag.Pop();
                        currentType.Pop();
                    }
                }


            }

        
        }


    }
}
